﻿using Aliyun.OSS;
using CKS.Core.Framework;
using CKS.PLC.Action.System;
using CKS.PLC.Core.Cache;
using CKS.PLC.Core.CronJob;
using CKS.PLC.Core.Reader;
using FreeSql;
using FreeSql.Internal.Model;
using Infrastructure;
using Microsoft.Extensions.DependencyInjection;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using ZR.Model.Models.ProductionControl;

namespace CKS.PLC.Action.Subscription
{
    public class Work01Action: SaveProcessingResults
    {
        SocketReaderClient ReaderClient;
        /// <summary>
        /// 申请入站 - 需要读取扫码器
        /// </summary>
        /// <param name="_value"></param>
        public Work01Action(DecodeValue _value) : base(_value)
        {
            ReaderClient = InternalApp.JobProvider.GetService<MonitorClientJob>().Client1;
        }

        public override AfterSaveResult AfterSaved(SaveArg e)
        {
            var barCode  = ReaderClient.GetReaderString();//获取扫码内容
            EventBus.AddLog($"托盘进站扫码内容:{barCode}");
            var P = Value.Position;
            var act = conn.Select<CksPlcActions>().Where(a => a.ActionType == 1 && a.PlcId == P.PlcId && a.ActionId == P.ActionId && a.ActionKey == P.ActionKey)
                .First();
            var replyPos = Value.GetReplyPosition(act.WriteDB, act.ActionId, act.ActionKey);
            var codePos = Value.GetReplyPosition(act.WriteDB, act.ActionId, act.ActionKey,1);

            //查询动态表记录，填充
            var fsqlTable = e.TableInfo;
            var dict = new Dictionary<string, object>();
            dict["Id"] = e.InsertIdentityId;
            dict["CheckResult"] = "2";
            object obj = null;
            //如果是空内容，说明是扫码NG。添加到异常任务表
            if (barCode.IsNoReade())
            {
               
                dict["ContainerNo"] = barCode;
                dict["Info"] = "扫码NG";
                obj = fsqlTable.CreateInstance(dict);
                conn.Update<object>().AsType(fsqlTable.Type)
                    .SetSource(obj).UpdateColumns(a => dict.Keys.ToArray()).ExecuteAffrows();

                var excep = new CksPackagingExceptionTask() { NgType = PackageNgType.扫码NG,Location = "入口位", ProductMode = ProductMode };
                ServiceCommon.ExceptionTasks.Add(excep);

                //回复流转数据空、回复信号 99 
                SiemensClient.SetValue(codePos,"");
                SiemensClient.SetValue(replyPos,"99");
                return new AfterSaveResult() { CanExecute = false };
            }


            //本次扫码是托盘号，需要查询托盘号最新绑定的数据
            var container = conn.Select<CksContainer>()
                .Where(a=>a.ContainerNo == barCode && a.ProductMode == ProductMode).First();

            if (InternalApp.DebugMode)
            {
                EventBus.AddLog($"托盘进站{barCode},调试模式");
                container = MockContainerCheck(barCode, container);

            }





            if (container == null)
            {
                EventBus.AddLog($"托盘进站{barCode},无订单信息");
                dict["ContainerNo"] = barCode;
                dict["Info"] = "无订单信息";
                obj = fsqlTable.CreateInstance(dict);
                conn.Update<object>().AsType(fsqlTable.Type)
                    .SetSource(obj).UpdateColumns(a => dict.Keys.ToArray()).ExecuteAffrows();

                var excep = new CksPackagingExceptionTask() { Location="入口位", NgType = PackageNgType.无订单信息,ProductMode =ProductMode };
                ServiceCommon.ExceptionTasks.Add(excep);
                //回复流转数据空、回复信号 99 
                SiemensClient.SetValue(codePos, "");
                SiemensClient.SetValue(replyPos, "99");
                return new AfterSaveResult() { CanExecute = false };
            }

            //找到容器绑定信息
            var task =conn.Select<CksPackagingTask>().Where(a => a.TaskNo == container.TaskNo && ProductMode == ProductMode ).First();
            task.TaskStatus = TaskStatusType.尺寸测量完成;
            task.Position = "尺寸测量位";
            task.InTime = DateTime.Now;
            task.StepNo = 1;
            conn.Update<CksPackagingTask>().SetSource(task).ExecuteAffrows();


            
            dict["TaskNo"] = task.TaskNo;
            dict["ContainerNo"] = task.ContainerNo;
            dict["WaybillNo"] = task.WaybillNo;
            dict["Info"] = "尺寸测量完成";
            obj = fsqlTable.CreateInstance(dict);
            conn.Update<object>().AsType(fsqlTable.Type)
                .SetSource(obj).UpdateColumns(a=> dict.Keys.ToArray()).ExecuteAffrows();

            UpdateFsqlTable(fsqlTable, dict);
            //检查尺寸
            if (e.RowData["MeasureLength"].ToInt() == 999)
            {
                
                EventBus.AddLog($"托盘进站{barCode},任务编号{task.TaskNo},长度不符合");

                var excep = new CksPackagingExceptionTask()
                {
                    NgType = PackageNgType.长度不符合,
                    TaskNo = task.TaskNo,
                    ContainerNo = task.ContainerNo,
                    ProductMode = ProductMode,
                };
                ServiceCommon.ExceptionTasks.Add(excep);
                //回复流转数据空、回复信号 99 
                SiemensClient.SetValue(codePos, "");
                SiemensClient.SetValue(replyPos, "99");
                return new AfterSaveResult() { CanExecute = false };
            }
            else if (e.RowData["MeasureWidth"].ToInt() == 999)
            {
                dict["CheckResult"] = "2";
                EventBus.AddLog($"托盘进站{barCode},任务编号{task.TaskNo},宽度不符合");
                var excep = new CksPackagingExceptionTask()
                {
                    NgType = PackageNgType.宽度不符合,
                    TaskNo = task.TaskNo,
                    ContainerNo = task.ContainerNo,
                    ProductMode = ProductMode,
                };
                ServiceCommon.ExceptionTasks.Add(excep);
                //回复流转数据空、回复信号 99 
                SiemensClient.SetValue(codePos, "");
                SiemensClient.SetValue(replyPos, "99");
                return new AfterSaveResult() { CanExecute = false };
            }
            else if (e.RowData["MeasureHeight"].ToInt() > 235)
            {
                dict["CheckResult"] = "2";
                EventBus.AddLog($"托盘进站{barCode},任务编号{task.TaskNo},高度不符合");
                var excep = new CksPackagingExceptionTask()
                {
                    NgType = PackageNgType.高度不符合,
                    TaskNo = task.TaskNo,
                    ContainerNo = task.ContainerNo, ProductMode = ProductMode,
                };
                ServiceCommon.ExceptionTasks.Add(excep);
                //回复流转数据空、回复信号 99 
                SiemensClient.SetValue(codePos, "");
                SiemensClient.SetValue(replyPos, "99");
                return new AfterSaveResult() { CanExecute = false };
            }

            dict["CheckResult"] = "1";
            UpdateFsqlTable(fsqlTable, dict);

            EventBus.AddLog($"托盘进站{barCode},任务编号{task.TaskNo},面单{task.WaybillNo},尺寸测量完成");

            //回复流转数据空、回复信号 99 
            SiemensClient.SetValue(codePos, task.TaskNo);
            SiemensClient.SetValue(replyPos, "20");
            return new AfterSaveResult() { CanExecute = false };
        }
        /// <summary>
        /// 模拟模式，检查托盘，生成模拟订单
        /// </summary>
        /// <param name="barCode"></param>
        /// <param name="container"></param>
        /// <returns></returns>
        private CksContainer MockContainerCheck(string barCode, CksContainer container)
        {
            if (container == null)
            {
                container = new CksContainer()
                {
                    ContainerNo = barCode,
                    CreatedTime = DateTime.Now,
                    Status = 0,
                    ProductMode = ProductMode,
                    TaskNo = string.Empty,
                };
                container.Id = fsql.Insert<CksContainer>(container).ExecuteIdentity();
            }

            if (container.Status == 0)
            {
                string dayCacheKey = $"Mock{DateTime.Now.ToString("yyMMdd")}";
                var nextSeriaNumber = ServiceCommon.GetNextSerialNumber(dayCacheKey);
                container.TaskNo = $"{dayCacheKey}{nextSeriaNumber.ToString().PadLeft(4, '0')}";
                container.Status = 1;
                container.WaybillNo = string.Empty;
                fsql.Update<CksContainer>().SetSource(container).ExecuteAffrows();
                //生成任务记录
                CksPackagingTask packagingTask = new CksPackagingTask()
                {
                    ContainerNo = container.ContainerNo,
                    CreatedTime = DateTime.Now,
                    OrderNo = "",
                    PackageNo = "",
                    Position = "投料口",
                    TaskStatus = TaskStatusType.接收订单信息,
                    TaskNo = container.TaskNo,
                    WaybillNo = container.TaskNo,
                    ProductMode = ProductMode
                };
                fsql.Insert(packagingTask).ExecuteAffrows();
            }

            return container;
        }

        private object UpdateFsqlTable(TableInfo fsqlTable, Dictionary<string, object> dict)
        {
            object obj = fsqlTable.CreateInstance(dict);
            conn.Update<object>().AsType(fsqlTable.Type)
                                .SetSource(obj).UpdateColumns(a => dict.Keys.ToArray()).ExecuteAffrows();
            return obj;
        }

        public override void BeforeReset()
        {
            var P = Value.Position;
            var act = conn.Select<CksPlcActions>().Where(a => a.ActionType == 1 && a.PlcId == P.PlcId && a.ActionId == P.ActionId && a.ActionKey == P.ActionKey)
                .First();
            var replyPos = Value.GetReplyPosition(act.WriteDB, act.ActionId, act.ActionKey);
            var codePos = Value.GetReplyPosition(act.WriteDB, act.ActionId, act.ActionKey, 1);
            SiemensClient.SetValue(codePos, string.Empty); //复位
        }
    }
}
